package org.start;

import java.util.Calendar;
import java.util.Date;
import java.util.regex.*;

// final 类
// final 类不能被继承，没有类能够继承 final 类的任何特性
final class Test {
    // 类体
}

// 报错无法从final类继承
// public class Class extends Test {}


// 抽象类
// 抽象方法是一种没有任何实现的方法，该方法的具体实现由子类提供。
// 抽象方法不能被声明成 final 和 static。
// 任何继承抽象类的子类必须实现父类的所有抽象方法，除非该子类也是抽象类。
// 如果一个类包含若干个抽象方法，那么该类必须声明为抽象类。抽象类可以不包含抽象方法。
// 抽象方法的声明以分号结尾。
abstract class Test1 {
    abstract void t1();

    abstract void t2();
}

class Test1_ extends Test1 {
    public void t1() {
        return;
    }

    public void t2() {
        return;
    }


    // synchronized 修饰符
    // synchronized 关键字声明的方法同一时间只能被一个线程访问。synchronized 修饰符可以应用于四个访问修饰符。
    public synchronized void showDetails() {
    }


    // volatile 修饰符
    // volatile 修饰的成员变量在每次被线程访问时，都强制从共享内存中重新读取该成员变量的值。而且，当成员变量发生变化时，会强制线程将变化值回写到共享内存。
    // 这样在任何时刻，两个不同的线程总是看到某个成员变量的同一个值。
    private volatile boolean active;

    public void run() {
        active = true;
        while (active) {
            System.out.println("fqmyysjjd");
        }
    }

    public void stop() {
        active = false;
    }
}

// 接口：与抽象类类似只不过是完全的抽象
// 其内部不能又实现
// 接口可以多继承，而extend不能多继承
interface Test2 {
    void fqmyysjjd();
    void fqmyybjjzw();
}

// 实现接口的类必须实现接口的所有抽象方法，或者声明为抽象类
class _Test2 implements Test2 {
    @Override
    public void fqmyybjjzw() {
        System.out.println("fqmyybjjzw");
    }

    @Override
    public void fqmyysjjd() {
        System.out.println("fqmyysjjd");
    }
}

class DateDemo {
    public void diffDemo() {
        Date date1 = new Date();
        System.out.println(date1);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.err.println(e);
        }
        Date date2 = new Date();
        System.out.println(date2);
        System.out.println(date2.getTime() - date1.getTime());
    }

    public void diffDemo2() {
        long time1 = System.currentTimeMillis();
        System.out.println(time1);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.err.println(e);
        }
        long time2 = System.currentTimeMillis();
        System.out.println(time2);
        System.out.println(time2 - time1);
    }

    public void calendarDemo() {
        // 不能用new创建
        Calendar calendar = Calendar.getInstance();
        calendar.set(2019, Calendar.DECEMBER, 13);
    }
}

class RegDemo {
    private static final String REG_EX = "^fqmyysjjd(.*)";

    public void testMatch() {
        Boolean res = Pattern.matches(REG_EX, "fqmyysjjddx");
        System.out.println(res);
    }

    public void testCompile() {
        Pattern regEx = Pattern.compile(REG_EX);
        Matcher matcher = regEx.matcher("fqmyysjjddx");
        // matcher判断是否能够找到
        if (matcher.find()) {
            System.out.println(matcher.group(0));
            System.out.println(matcher.group(1));
        }
    }
}


public class Class {
    public interface Func {
        void function();
    }

    public static void await(int timeInterval) {
        try {
            Thread.sleep(timeInterval);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    // 不同线程修改同一个变量，使用volatile修饰后强制更新
    static void testVolatile() {
        Test1_ t1 = new Test1_();

        new Thread(() -> {
            System.out.println("开始了一个线程" + new Date());
            await(1000);
            t1.run();
        }).start();

        new Thread(() -> {
            System.out.println("开始了一个线程" + new Date());
            await(2000);
            t1.stop();
        }).start();
    }

    public static void testDate() {
        DateDemo dateDemo = new DateDemo();
        // dateDemo.diffDemo();
        // dateDemo.diffDemo2();
        dateDemo.calendarDemo();
    }

    public static void testReg() {
        RegDemo regDemo = new RegDemo();
        regDemo.testMatch();
        regDemo.testCompile();
    }

    public static void main(String[] args) {
        // testDate();
        testReg();
    }
}
